#include <iostream>
#include <string>
#include <windows.h>
#include "gameData.h"
using namespace std;

/*--- De/Constructors ---*/
GameData::GameData(SDL_Surface *a_buffer) : buffer(a_buffer),
running(true), noFreeDice(false), noRoll(false),
gameState(0), gameRound(0), turnRound(0), currentPlayer(0),
font(NULL)
{
	uiElement = new SDL_Surface();
	int i = 0;
	uiTextColor.r = 255;
	uiTextColor.g = 255;
	uiTextColor.b = 255;
	//initalize mouse position
	mPos.x = mPos.y = 0;

	uiElement = load_image("ui.png");
	font = loadFont("wbv4.ttf",24);
	//font = TTF_OpenFont("wbv4.ttf",24);
	players = new Player[TWO_PLAYERS];
	for(i=0; i< TWO_PLAYERS; i++) {players[i].initialize(i,0,uiTextColor,font);}

	// allocate memory and initialize
	uiMenu1 = new UserInterface[UI_INFO_ITEMS];
	for(i = 0; i < UI_INFO_ITEMS; i++){
		uiMenu1[i].menuPos.x = uiMenu1[i].menuPos.y = uiMenu1[i].rect.x = uiMenu1[i].rect.y = 0;
		uiMenu1[i].rect.h = uiMenu1[i].rect.w = uiMenu1[i].height = uiMenu1[i].width = 0;
	}

	// store strings in surfaces
	gRoundText = TTF_RenderText_Solid(font, G_ROUND_TEXT.c_str(), uiTextColor);
	pTurnText = TTF_RenderText_Solid(font, P_TURN_TEXT.c_str(), uiTextColor);
	nTurnText = TTF_RenderText_Solid(font, NEXT_PLAYER.c_str(), uiTextColor);

	// set the ui eleemnts for the ui text
	uiMenu1[0].menuPos.x = UI_LOC_X;
	uiMenu1[0].menuPos.y = buffer->h - gRoundText->h;
	uiMenu1[0].rect.w = uiMenu1[0].width = gRoundText->w;
	uiMenu1[0].rect.h = uiMenu1[0].height = gRoundText->h;
	uiMenu1[1].menuPos.x = buffer->w/2;
	uiMenu1[1].menuPos.y = buffer->h - pTurnText->h;
	uiMenu1[1].rect.w = uiMenu1[1].width = pTurnText->w;
	uiMenu1[1].rect.h = uiMenu1[1].height = pTurnText->h;
	uiMenu1[2].menuPos.x = buffer->w - nTurnText->w;
	uiMenu1[2].menuPos.y = buffer->h - nTurnText->h;
	uiMenu1[2].rect.w = uiMenu1[1].width = nTurnText->w;
	uiMenu1[2].rect.h = uiMenu1[1].height = nTurnText->h;
}

GameData::~GameData()
{
	Release();
}

/*--- Basic Game Functions ---*/
void GameData::update()
{
	// performs operations according to state
	switch(gameState)
	{
	case NO_ACTION:
			break;
	case GAME_END: // ends the program
		running = false;
		break;
	case ROUND_START: // starts a new game
		break;
	case ROUND_END:   // ends the current game, displays winner.
		break;
	case CHANGE_PLAYER:
		// reset turn
		gameState = NO_ACTION;
		// 0 == PLAYER_IDLE
		players[currentPlayer].setGameState(0);
		turnRound = 0;
		gameRound++;
		players[currentPlayer].unFreezeAll();
		noRoll = false;

		if(currentPlayer!=(TWO_PLAYERS-1)){
			currentPlayer++;
		}
		else{
			currentPlayer=0;
		}
		// refresh dice after scoring
		players[currentPlayer].diceRollAll();
		gameState = NO_ACTION;
		break;
	case PLAYER_TURN:
		if(players[currentPlayer].allFrozen()){
			noRoll = true;
		}
		else if(turnRound == MAX_REROLL){
			noRoll = true;
			// 0 == PLAYER_IDLE
			players[currentPlayer].setGameState(0);
		}
		else{
			players[currentPlayer].update(buffer,mPos);
			turnRound++;
			gameState = NO_ACTION;
			// 0 == PLAYER_IDLE
			players[currentPlayer].setGameState(0);
		}
		break;
	case SCORING:
		if(players[currentPlayer].allScored()){
			gameState = ROUND_END;
		}
		else{
			players[currentPlayer].update(buffer,mPos);
			// 0 == PLAYER_IDLE
			players[currentPlayer].setGameState(0);
		}
		break;
	}
}

void GameData::handleInput()
{
	SDL_Event e;
	while(SDL_PollEvent(&e)){
		switch(e.type){
			case SDL_KEYDOWN:
				switch(e.key.keysym.sym){
			case SDLK_ESCAPE:
				gameState = GAME_END;
				break;
				}
				break;
			case SDL_MOUSEMOTION:
				mPos.x = e.motion.x;
				mPos.y = e.motion.y;
				break;
			case SDL_MOUSEBUTTONDOWN:
				mouseButtonClicked();
			case SDL_MOUSEBUTTONUP:
				break;
		}
	}
}

void GameData::draw()
{
	Clear(); // blanks the buffer

	//x,y,w,h positions & dimensions
	SDL_Rect uiRect = {0, (buffer->h - uiElement->h), uiElement->w, uiElement->h}; 
	drawTile(uiElement, &uiRect, 0, buffer, UI_LOC_X, (buffer->h - uiElement->h));
	drawTile(gRoundText, &uiMenu1[0].rect, 0, buffer, uiMenu1[0].menuPos.x, uiMenu1[0].menuPos.y);
	drawTile(pTurnText, &uiMenu1[1].rect, 0, buffer, uiMenu1[1].menuPos.x, uiMenu1[1].menuPos.y);
	drawTile(nTurnText, &uiMenu1[2].rect, 0, buffer, uiMenu1[2].menuPos.x, uiMenu1[2].menuPos.y);

	// draw game Round and turn info on bottom of screen
	SDL_Surface * text_surface1, *text_surface2;
	SDL_Rect text_rect = {0,0,0,0};
	char* t_number = new char[sizeof(char)];
	_itoa(gameRound,t_number,10);
	text_surface1 = TTF_RenderText_Solid(font,t_number, uiTextColor);
	text_rect.w = text_surface1->w;
	text_rect.h = text_surface1->h;
	drawTile(text_surface1,&text_rect,0,buffer,uiMenu1[0].width, buffer->h - text_surface1->h);

	_itoa(turnRound,t_number,10);
	text_surface2 = TTF_RenderText_Solid(font,t_number, uiTextColor);
	text_rect.w = text_surface2->w;
	text_rect.h = text_surface2->h;
	drawTile(text_surface2,&text_rect,0,buffer,uiMenu1[1].width + uiMenu1[1].menuPos.x, buffer->h - text_surface2->h);
	
	// draw player class to screen
	players[currentPlayer].draw(buffer);
	// draw to the screen
	SDL_Flip(buffer);

	// free unused surfaces
	SDL_FreeSurface(text_surface1);
	SDL_FreeSurface(text_surface2);
}

void GameData::Release()
{
	delete[] players;
	delete[] uiMenu1;
	SDL_FreeSurface(uiElement);
	SDL_FreeSurface(gRoundText);
	SDL_FreeSurface(pTurnText);
}

void GameData::mouseButtonClicked()
{
	int tX = 0, tX2 = 0, tY = 0, tY2 = 0; // temp position variables;
	if((mPos.y > (buffer->h - uiElement->h) && mPos.y < buffer->h) &&
		(mPos.x > 0 && mPos.x < buffer->w)){
			if((mPos.x > uiMenu1[2].menuPos.x && mPos.x < buffer->w) &&
				(mPos.y > uiMenu1[2].menuPos.y && mPos.y < buffer->h)){
					gameState = CHANGE_PLAYER;
			}
			else{
				for(int i = 0; i < UI_MENU_ITEMS; i++){
					tX = ((uiElement->w/UI_MENU_ITEMS) * i);
					tX2 = ((uiElement->w/UI_MENU_ITEMS) * (i+1));
					if(mPos.x > tX && mPos.x < tX2){
						switch(i)
						{
						case 0:
							gameState = ROUND_START;
							break;
						case 1:
							gameState = PLAYER_TURN;
							// 1 == PLAYER_ROLL
							players[currentPlayer].setGameState(1);
							break;
						case 2: // fall through - case bracket
						case 3: // for proper case.
						case 4:
						case 5:
						case 6:
							players[currentPlayer].freezeDiceValue(i-2);
							break;
						}
					}
				}
			}
	}
	else if(players[currentPlayer].isScoreClicked(mPos,buffer->w)){
		if(turnRound != 0){
			// Not a magic number 2 == PLAYER_SCORE
			players[currentPlayer].setGameState(2);
			gameState = SCORING;
		}
	}
}

void GameData::Clear()
{
	SDL_Rect t_rect = {0,0,buffer->w,buffer->h};
	SDL_FillRect(buffer,&t_rect,000000);
}

TTF_Font* GameData::loadFont(char* file, int size)
{
	TTF_Font* font;
	font = TTF_OpenFont(file, size);
	if( font == NULL)
	{
		printf_s("Unable to load font: %s %s \n", file, TTF_GetError());
	}
	return font;
}